package com.yanqu.road.server.manger.activity.dragonboatrace;

import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.dragonboatrace.*;
import com.yanqu.road.entity.activity.dragonboatrace.config.DragonBoatRaceConfig;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogDragonBoatRaceGame;
import com.yanqu.road.entity.task.args.UnionRiseRankArgs;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.logic.bussiness.activity.DragonBoatRaceBusiness;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.logic.pb.UnionBasePb;
import com.yanqu.road.pb.dragonboatrace.DragonBoatRaceProto;
import com.yanqu.road.pb.union.UnionProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.activity.dragonboatrace.DragonBoatRaceModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Description 赛龙舟
 * @Author cwq
 * @Data 2021/5/11 11:47
 */
public class DragonBoatRaceMgr extends TempMgr {

    private static ActivityInfo activityInfo;

    private static DragonBoatRaceConfig config;

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        return true;
    }

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {
        return true;
    }

    public static ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public static void reloadActivityData(){
        getLogger().info("reload dragon boat race activity start");
        // 获取活动
        List<ActivityInfo> openActivityInfoList = NormalActivityMgr.getOpenActivityInfoList(eActivityType.DragonBoatRaceActivity.getValue());
        if (openActivityInfoList.size() <= 0) {
            activityInfo = null;
            config = null;
            return;
        }
        activityInfo = openActivityInfoList.get(0);

        List<Integer> activityIdList = new ArrayList<>();
        activityIdList.add(activityInfo.getActivityId());
        Map<String, ActivityConfig> activityConfigMap = ActivityBussiness.getActivityConfigMap(activityIdList).get(activityInfo.getActivityId());
        DragonBoatRaceConfig dragonBoatRaceConfig = new DragonBoatRaceConfig();
        dragonBoatRaceConfig.setPlaceConfigList(DragonBoatRaceBusiness.getDragonBoatRacePlaceConfigList(activityInfo.getActivityId()));
        dragonBoatRaceConfig.setSpeedList(DragonBoatRaceBusiness.getDragonBoatRaceSpeedConfigList(activityInfo.getActivityId()));
        dragonBoatRaceConfig.parseConfig(activityConfigMap);

        config = dragonBoatRaceConfig;

        // 同步数据
        for (GamePlayer gamePlayer : GamePlayerMgr.getAllOnlinePlayer()) {
            DragonBoatRaceModule dragonBoatRaceModule = gamePlayer.getModule(DragonBoatRaceModule.class);
            // 同步活动数据
            dragonBoatRaceModule.syncConfig();
            // 同步玩家数据
            dragonBoatRaceModule.initUserData();
            dragonBoatRaceModule.syncUserData();
        }

        getLogger().info("reload dragon boat race activity end");
    }

    /**
     * 获取展示中的活动ID（0表示没活动）
     */
    public static int getShowTimeActivityId() {
        return activityInfo == null ? 0 : activityInfo.getActivityId();
    }

    /**
     * 活动期间
     * @param player
     * @return
     */
    public static int getActivityEndStatus(GamePlayer player){
        int ret = 0;
        if(DragonBoatRaceMgr.getShowTimeActivityId() == 0){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        if(!ActivityMgr.activityInTime(DragonBoatRaceMgr.activityInfo)){
            return GameErrorCode.E_DRAGONBOATRACE_ACTIVITY_NO_IN_TIME;
        }
        // 判断是否解锁
        if(!SystemOpenMgr.systemOpen(player, eSystemId.DragonBoatRaceActivity.getValue())){
            return GameErrorCode.E_DRAGONBOATRACE_ACTIVITY_NO_UNLOCK;
        }
        return ret;
    }

    /**
     * 活动期间和显示期间
     * @param player
     * @return
     */
    public static int getActivityShowStatus(GamePlayer player){
        int ret = 0;
        if(DragonBoatRaceMgr.getShowTimeActivityId() == 0){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        if(!ActivityMgr.activityInTimeAndShowTime(DragonBoatRaceMgr.activityInfo)){
            return GameErrorCode.E_DRAGONBOATRACE_ACTIVITY_NO_IN_TIME;
        }
        // 判断是否解锁
        if(!SystemOpenMgr.systemOpen(player, eSystemId.DragonBoatRaceActivity.getValue())){
            return GameErrorCode.E_DRAGONBOATRACE_ACTIVITY_NO_UNLOCK;
        }
        return ret;
    }

    /**
     * 是否休息时间
     */
    public static boolean isRestTime() {
        int hours = DateHelper.getHours();
        return hours < DragonBoatRaceMgr.getConfig().getDRAGONBOATRACE_DAILY_OPEN_TIME() || hours >= DragonBoatRaceMgr.getConfig().getDRAGONBOATRACE_DAILY_END_TIME();
    }


    public static DragonBoatRaceProto.DragonBoatRaceNodeInfoEntity builderDragonBoatRaceNodeInfoEntity(DragonBoatRaceUser dragonBoatRaceUser){
        DragonBoatRaceProto.DragonBoatRaceNodeInfoEntity.Builder builder = DragonBoatRaceProto.DragonBoatRaceNodeInfoEntity.newBuilder();
        builder.setTime(dragonBoatRaceUser.curCalTime);
        builder.setSpeed(dragonBoatRaceUser.curSpeed);
        builder.setDistance(dragonBoatRaceUser.distance);
        builder.setMeetObstacleDistance(dragonBoatRaceUser.produceObstacleDistance);
        return builder.build();
    }

    /**
     * 同步玩家联盟奖励红点
     * @param userId
     */
    public static void syncPlayerRedPoint(long userId) {
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (player != null) {
            player.getModule(DragonBoatRaceModule.class).synRedPointToCross();
        }
    }

    /**
     * 同步玩家联盟奖励红点
     * @param userId
     */
    public static void syncPlayerRedPoint(long userId,boolean hasUnionReward) {
        GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
        if (player != null) {
            player.getModule(DragonBoatRaceModule.class).synRedPoint(hasUnionReward);
        }
    }

    /**
     * 联盟升级 需要 重新计算积分 和 刷新红点
     * @param unionId
     */
    public static void unionLevelUp(String unionId){
        int activityId = DragonBoatRaceMgr.getShowTimeActivityId();
        if (activityId == 0) {
            return;
        }
        // 通知活动跨服 更新跨服
        DragonBoatRaceProto.DragonBoatRaceSynUnionInfoGameToCrossMsg.Builder builder = DragonBoatRaceProto.DragonBoatRaceSynUnionInfoGameToCrossMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setType(0);
        builder.setUnionId(unionId);
        UnionBaseInfo unionBaseInfo = CrossUnionMgr.parseUnionBaseInfo(unionId);
        UnionProto.UnionBaseTempMsg.Builder unionTempMsg = UnionBasePb.parseUnionBaseTempMsg(unionBaseInfo);
        builder.setUnionBase(unionTempMsg);

        GamePlayerMgr.sendPacket(0, YanQuMessageUtils.buildMessage(CrossProtocol.C2_DRAGONBOATRACE_SYN_UNION_INFO, builder));
    }

    public static DragonBoatRaceModule getDragonBoatRaceModule(GamePlayer player){
        DragonBoatRaceModule dragonBoatRaceModule = player.getModule(DragonBoatRaceModule.class);
        dragonBoatRaceModule.initUserData();
        dragonBoatRaceModule.refresh();
        return dragonBoatRaceModule;
    }

    public static DragonBoatRaceProto.DragonBoatRaceEndRespMsg.Builder endGame(GamePlayer player){
        DragonBoatRaceProto.DragonBoatRaceEndRespMsg.Builder builder = DragonBoatRaceProto.DragonBoatRaceEndRespMsg.newBuilder();
        DragonBoatRaceModule dragonBoatRaceModule = player.getModule(DragonBoatRaceModule.class);
        if(DragonBoatRaceMgr.getActivityInfo() == null){
            builder.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
            return builder;
        }
        long cutTime = System.currentTimeMillis();
        if(cutTime >= DragonBoatRaceMgr.getActivityInfo().getEndTime() * 1000){
            builder.setRet(GameErrorCode.E_DRAGONBOATRACE_ACTIVITY_NO_IN_TIME);
            return builder;
        }
        if(dragonBoatRaceModule.dragonBoatRaceUser == null || dragonBoatRaceModule.dragonBoatRaceUser.startTime <= 0){
            builder.setRet(GameErrorCode.E_DRAGONBOATRACE_NOT_JOIN_GAME) ;
            return builder;
        }
        if (cutTime < dragonBoatRaceModule.dragonBoatRaceUser.endTime){
            builder.setRet(GameErrorCode.E_DRAGONBOATRACE_NOT_END) ;
            return builder;
        }
        dragonBoatRaceModule.refreshGame(dragonBoatRaceModule.dragonBoatRaceUser.endTime);
        CurrencyModule currencyModule = player.getModule(CurrencyModule.class);
        for (Map.Entry<Integer,Integer> entry : dragonBoatRaceModule.dragonBoatRaceUser.usePropMap.entrySet()){
            Property property = new Property(entry.getKey(), BigInteger.valueOf(entry.getValue()));
            if(!currencyModule.currencyIsEnough(property)){
                dragonBoatRaceModule.clearGame();
                builder.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH) ;
                return builder;
            }
        }
        // 扣道具
        StringBuilder usePropSB = new StringBuilder();
        for (Map.Entry<Integer,Integer> entry : dragonBoatRaceModule.dragonBoatRaceUser.usePropMap.entrySet()){
            Property property = new Property(entry.getKey(), BigInteger.valueOf(entry.getValue()));
            currencyModule.removeCurrency(property, eLogMoneyType.DragonBoatRaceActivity,eLogMoneyType.DragonBoatRaceActivityUserPropCost);
            usePropSB.append(entry.getKey()).append(",").append(entry.getValue()).append("|");
        }
        for(Map.Entry<Integer,Integer> entry : dragonBoatRaceModule.dragonBoatRaceUser.useFreePropMap.entrySet()){
            usePropSB.append(entry.getKey()).append(",").append(entry.getValue()).append("|");
        }
        String usePropStr = "";
        if(usePropSB.length() > 0) {
            usePropStr = usePropSB.substring(0,usePropSB.length()-1);
        }
        dragonBoatRaceModule.dragonBoatRaceUser.baseData.setLastTimeJoinTime((int)(cutTime / 1000));
        dragonBoatRaceModule.dragonBoatRaceUser.baseData.setTimes(dragonBoatRaceModule.dragonBoatRaceUser.baseData.getTimes() + 1);
        dragonBoatRaceModule.dragonBoatRaceUser.baseData.getPatronsList().addAll(dragonBoatRaceModule.dragonBoatRaceUser.patronsList);
        dragonBoatRaceModule.dragonBoatRaceUser.baseData.setUpdateOption();

        builder.setRet(0);
        //派遣的门客领奖
        long realDistance = dragonBoatRaceModule.dragonBoatRaceUser.distance / 100;
        int exp = (int)((realDistance * DragonBoatRaceMgr.getConfig().getDRAGONBOATRACE_PATRONS_EXP_COEFFICIENT_1() + DragonBoatRaceMgr.getConfig().getDRAGONBOATRACE_PATRONS_EXP_COEFFICIENT_2() - 1) / DragonBoatRaceMgr.getConfig().getDRAGONBOATRACE_PATRONS_EXP_COEFFICIENT_2());
        PatronsModule patronsModule = player.getModule(PatronsModule.class);
        for (Integer patronsId : dragonBoatRaceModule.dragonBoatRaceUser.patronsList) {
            patronsModule.addBaiYeExp(patronsId,exp);
            builder.addPatronsExp(DragonBoatRaceProto.DragonBoatRacePatronsExpEntity.newBuilder().setId(patronsId).setExp(exp));
        }
        // 加积分
        currencyModule.addCurrency(new Property(DragonBoatRaceMgr.getConfig().getDRAGONBOATRACE_SCORE_ITEM_ID(), BigInteger.valueOf(realDistance)),
                eLogMoneyType.DragonBoatRaceActivity, eLogMoneyType.DragonBoatRaceActivityEndReward);
        // 加排行
        player.notifyListener(eGamePlayerEventType.DragonBoatRaceActivityScoreRank.getValue(), realDistance);
        player.notifyListener(eGamePlayerEventType.DragonBoatRaceActivityScoreCrossRank.getValue(), realDistance);

        // 加日志
        String patrons = StringUtils.listToString(dragonBoatRaceModule.dragonBoatRaceUser.patronsList,";");
        int patronPlus = dragonBoatRaceModule.dragonBoatRaceUser.initSpeed - DragonBoatRaceMgr.getConfig().getDRAGONBOATRACE_INIT_SPEED();

//        LogMgr.addLogDragonBoatRaceGame(new LogDragonBoatRaceGame(activityInfo.getActivityId(),dragonBoatRaceModule.dragonBoatRaceUser.baseData.getUserId(),patrons,patronPlus,exp,usePropStr.toString(),
//                dragonBoatRaceModule.dragonBoatRaceUser.breakObstacleNum + dragonBoatRaceModule.dragonBoatRaceUser.unBreakObstacleNum,dragonBoatRaceModule.dragonBoatRaceUser.breakObstacleNum,dragonBoatRaceModule.dragonBoatRaceUser.unBreakObstacleNum,
//                dragonBoatRaceModule.dragonBoatRaceUser.clickDrumNum,(int)realDistance,cutTime));
        AutoLogMgr.add(new LogDragonBoatRaceGame(activityInfo.getActivityId(),dragonBoatRaceModule.dragonBoatRaceUser.baseData.getUserId(),patrons,patronPlus,exp,usePropStr.toString(),
                dragonBoatRaceModule.dragonBoatRaceUser.breakObstacleNum + dragonBoatRaceModule.dragonBoatRaceUser.unBreakObstacleNum,dragonBoatRaceModule.dragonBoatRaceUser.breakObstacleNum,dragonBoatRaceModule.dragonBoatRaceUser.unBreakObstacleNum,
                dragonBoatRaceModule.dragonBoatRaceUser.clickDrumNum,(int)realDistance,cutTime));
        player.notifyListener(eGamePlayerEventType.DragonBoatRaceActivityUnionScoreRank.getValue(), new UnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(realDistance), player.getUserInfo().getUnionUid()));
        player.notifyListener(eGamePlayerEventType.DragonBoatRaceActivityUnionScoreCrossRank.getValue(), new UnionRiseRankArgs(UnionRiseRankArgs.NOTIFY_TYPE_NORMAL, BigInteger.valueOf(realDistance), player.getUserInfo().getUnionUid()));
        if(!StringUtils.isNullOrEmpty(player.getUserInfo().getUnionUid())){
            // 加入航行记录
            DragonBoatRaceProto.DragonBoatRaceAddVoyageRecordGameToCrossMsg.Builder gameToCrossMsg = DragonBoatRaceProto.DragonBoatRaceAddVoyageRecordGameToCrossMsg.newBuilder();
            gameToCrossMsg.setActivityId(DragonBoatRaceMgr.getActivityInfo().getActivityId());
            gameToCrossMsg.setUnionId(player.getUserInfo().getUnionUid());
            gameToCrossMsg.setUserId(player.getUserId());
            gameToCrossMsg.setRealDistance(realDistance);
            gameToCrossMsg.setCutTime(cutTime);
            UnionBaseInfo unionBaseInfo = CrossUnionMgr.parseUnionBaseInfo(player.getUserInfo().getUnionUid());
            UnionProto.UnionBaseTempMsg.Builder unionTempMsg = UnionBasePb.parseUnionBaseTempMsg(unionBaseInfo);
            gameToCrossMsg.setUnionBase(unionTempMsg);
            gameToCrossMsg.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId())));

            player.sendPacket(CrossProtocol.C2_DRAGONBOATRACE_ADD_VOYAGE_RECORD, gameToCrossMsg);
        }
        builder.setDistance(realDistance);
        builder.setScore(realDistance);
        // 清空比赛
        dragonBoatRaceModule.clearGame();
        return builder;
    }


    public static DragonBoatRaceConfig getConfig() {
        return config;
    }

}
